iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Mobile Development

寫Jetpack Compose ,會很有畫面哦!系列 第 15

寫Jetpack Compose ,會很有畫面哦! - Day15 Compose 的版面配置 part3

  • 分享至 

  • xImage
  •  

Compose 的版面配置 Layouts

Jetpack Compose 可協助您為應用程式輕鬆設計高效率的版面配置。
以下頁面詳細介紹如何設計和實作版面配置:
  • Layout basics 版面配置基本概念:瞭解直觀應用程式 UI 的建構模塊。
  • Material Components and layouts 質感元件和版面配置:瞭解 Compose 的質感元件和版面配置。
  • Custom layouts 自訂版面配置:瞭解如何控管應用程式的版面配置,以及如何設計自己的自訂版面配置。
  • Build adaptive layouts 建立自動調整版面配置:瞭解如何使用 Compose 根據不同螢幕大小、方向和板型規格建構版面配置。
  • Alignment lines 對齊線條:瞭解如何建立自訂對齊線條,以精確對齊並定位 UI 元素。
  • Intrinsic measurements 固有測量尺寸:瞭解如何為 UI 元素設定固有高度或寬度,讓您精確控管元素在版面配置中的編排方式。
  • ConstraintLayout:瞭解如何在 Compose UI 中使用 ConstraintLayout。

Custom layouts 自訂版面配置

元素中有子項元素,就可通過測量每個子項以協助決定其大小。元素決定並回報其大小後,就有可以算出子項元素相對的位置。

在 UI 樹狀結構中完成每個節點的版面配置需要三個步驟。每個節點必須:

  1. 測量任何子項
  2. 決定其大小
  3. 放置其子項

https://ithelp.ithome.com.tw/upload/images/20220921/20121643X9e6LwD2lN.png

Using the layout modifier 使用版面配置輔助鍵

設計一條baseline的元件來重新計算text放的位置。
  1. 在透過呼叫 measurable.measure(constraints) 的方式,測量 Text 的參數。
  2. 透過呼叫 layout(width, height) 的方式,從新計算上一個基準及新增頂端邊框間距的高度。
  3. 呼叫 placeable.place(x, y),就可以把 Text 到計算好的位置
fun Modifier.firstBaselineToTop(
    firstBaselineToTop: Dp
) = layout { measurable, constraints ->
    // Measure the composable
    val placeable = measurable.measure(constraints)

    // Check the composable has a first baseline
    check(placeable[FirstBaseline] != AlignmentLine.Unspecified)
    val firstBaseline = placeable[FirstBaseline]

    // Height of the composable with padding - first baseline
    val placeableY = firstBaselineToTop.roundToPx() - firstBaseline
    val height = placeable.height + placeableY
    layout(placeable.width, height) {
        // Where the composable gets placed
        placeable.placeRelative(0, placeableY)
    }
}

使用BasicLine 來計算padding

@Composable
fun Greeting(name: String,modifier: Modifier = Modifier) {
    Text("Hi MyCustomBasicLine!", Modifier.firstBaselineToTop(32.dp))
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220921/20121643NCzKpnjnlF.png

使用Text預設,來計算padding

@Composable
fun Greeting(name: String,modifier: Modifier = Modifier) {
    Text("Hi MyCustomBasicLine!", Modifier.padding(top = 32.dp))
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220921/201216435dDhRPZH0P.png

Creating custom layouts 建立自訂版面配置

使用Layout 加上 Column or Row 建立自訂版面配置
@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // Don't constrain child views further, measure them with given constraints
        // List of measured children
        val placeables = measurables.map { measurable ->
            // Measure each children
            measurable.measure(constraints)
        }

        // Set the size of the layout as big as it can
        layout(constraints.maxWidth, constraints.maxHeight) {
            // Track the y co-ord we have placed children up to
            var yPosition = 0

            // Place children in the parent layout
            placeables.forEach { placeable ->
                // Position item on the screen
                placeable.placeRelative(x = 0, y = yPosition)

                // Record the y co-ord placed up to
                yPosition += placeable.height
            }
        }
    }
}

@Composable
fun Greeting(name: String,modifier: Modifier = Modifier) {
    
    MyBasicColumn(modifier.padding(8.dp)) {
        Text("MyCustomBasic")
        Text("places items")
        Text("vertically.")
        Text("Custom Layout !")
    }
}

顯示結果
https://ithelp.ithome.com.tw/upload/images/20220921/201216432FHVdkoLV7.png
https://ithelp.ithome.com.tw/upload/images/20220921/20121643FDvIjR9gp5.png

這樣子是不是算自義的 wrap_content 呀

參考:

https://developer.android.com/jetpack/compose/layouts/custom


上一篇
寫Jetpack Compose ,會很有畫面哦! - Day14 Compose 的版面配置 Part2
下一篇
寫Jetpack Compose ,會很有畫面哦! - Day16 Compose 的版面配置 part4
系列文
寫Jetpack Compose ,會很有畫面哦!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言